package com.meta.api.service.propagationService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.meta.api.mapper.TrancaTestMapper;
import com.meta.api.mapper.UserMapper;
import com.meta.api.param.UserNamePwdParam;
import com.meta.api.po.UserModel;

/**
 * @Author: xieZW
 * @Date: 2021/11/17 16:46
 * <p>
 * 测试传播特性
 */
@Component
public class TrancaPropagationA {

    @Autowired
    private UserMapper userDao;
    @Autowired
    private TrancaPropagationB trancaPropagationB;
    @Autowired
    private TrancaTestMapper trancaTestMapper;

    static UserModel userModel = new UserModel();

    static {
        userModel.setUserId(1L);
    }

    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void update(UserNamePwdParam param) {

        this.userDao.delete(userModel);
        trancaPropagationB.methodB(param);
    }

    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void update02(UserNamePwdParam param) {

        this.userDao.delete(userModel);
        trancaPropagationB.methodB02(param);
        throw new RuntimeException("我是A,管不着B，我A要回滚了，B你不跟着回滚吗！");
    }

    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void update03(UserNamePwdParam param) {

        this.userDao.delete(userModel);
        trancaPropagationB.methodB03(param);
    }

    public void update04(UserNamePwdParam param) {

        this.userDao.delete(userModel);
        trancaPropagationB.methodB04(param);
    }

    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void update05(UserNamePwdParam param) {

        this.userDao.delete(userModel);
        trancaPropagationB.methodB05(param);
        throw new RuntimeException("我是A,我报错我不会删除数据，但是B会插入新的数据");
    }

    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void update06(UserNamePwdParam param) {

        this.userDao.delete(userModel);
        trancaPropagationB.methodB06(param);
    }

    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void update07(UserNamePwdParam param) {

        this.userDao.delete(userModel);
        trancaPropagationB.methodB07(param);
        throw new RuntimeException("我是A,我报错我不会删除数据，B不会插入新的数据，因为B是SUPPORTS");
    }


    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void update09(UserNamePwdParam param) {

        userModel.setUserId(100L);
        this.userDao.delete(userModel);
        trancaPropagationB.methodB09(param);
    }

    @Transactional(rollbackFor = Exception.class, propagation = Propagation.NOT_SUPPORTED)
    public void update10(UserNamePwdParam param) {

        this.userDao.updateTest(userModel);
        System.out.println("我要死锁了！！！！！");
    }

    @Transactional(rollbackFor = Exception.class, propagation = Propagation.NOT_SUPPORTED)
    public void update11(UserNamePwdParam param) {

        deleteUser();
        System.out.println("我要死锁了！！！！！");
    }

    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
    public void deleteUser() {

        this.userDao.updateTest(userModel);
        throw new RuntimeException("xxxxxxxxxx");
    }


    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
    public void deleteUser22() {

        this.userDao.updateTest(userModel);
    }


    @Transactional(rollbackFor = Exception.class, propagation = Propagation.NOT_SUPPORTED)
    public void update12(UserNamePwdParam userNamePwdParamUpdate) {

        this.userDao.updateTest(userModel);
        deleteUser();
    }


    @Transactional(rollbackFor = Exception.class, propagation = Propagation.NOT_SUPPORTED)
    public void update13(UserNamePwdParam userNamePwdParamUpdate) throws InterruptedException {

        //这边先修改
        for (int i = 0; i < 5; i++) {
            this.deleteUser22();
        }

        //这边再修改
        for (int i = 0; i < 10; i++) {
            trancaPropagationB.sleepTwo(i);
        }
    }

    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
    public void update14(UserNamePwdParam userNamePwdParamUpdate) {

        for (int i = 0; i < 40; i++) {
//            System.out.println("i = " + Thread.currentThread().getName() + "更新了.......");
            this.deleteUser22();
            trancaPropagationB.deleteUser();
        }
    }

    @Transactional(rollbackFor = Exception.class, propagation = Propagation.NOT_SUPPORTED)
    public void update15(Object o) {

        for (int i = 0; i < 40; i++) {
//            System.out.println("i = " + Thread.currentThread().getName() + "更新了.......");
            this.deleteUser22();
            trancaPropagationB.deleteUser();
        }
    }

    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
    public void update16() {

        trancaPropagationB.deleteUser();
    }

    @Transactional
    public void update17() {

        userModel.setUsername("小王");
        trancaTestMapper.updateTest01(userModel);
//        throw new RuntimeException("xxx");
        int a = 1 / 0;
        userModel.setUsername("小李");
        trancaTestMapper.updateTest02(userModel);
    }
}
